/* 
 * File:   RldSerialPort.cpp
 * Author: batista
 * 
 * Created on 7 de Março de 2013, 13:35
 */

#include "RldSerialPort.h"

RldSerialPort::RldSerialPort() {
    m_port = new SerialStream();
}

RldSerialPort::~RldSerialPort() {
    m_port->Close();
}

/**
 * Seta a porta serial aberta
 * @param port
 */
void RldSerialPort::SetSerialPort(string serial_name) {
    //
    m_port = new SerialStream();
    
    //Modo de abertura da porta 
    ios_base::openmode mode = ios_base::in | ios_base::out;

    //Abre a porta
    m_port->Open(serial_name, mode);

    /**
     * Verifica se a porta foi aberta
     * @param serial_name
     */
    if (!m_port->good()) {
        cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
                << "Error: Could not open serial port."
                << endl;
    }

    //
    // Set the baud rate of the serial port.
    //
    m_port->SetBaudRate(SerialStreamBuf::BAUD_9600);

    if (!m_port->good()) {
        std::cerr << "Error: Could not set the baud rate." << std::endl;
        exit(1);
    }
    //
    // Set the number of data bits.
    //
    m_port->SetCharSize(SerialStreamBuf::CHAR_SIZE_8);
    if (!m_port->good()) {
        std::cerr << "Error: Could not set the character size." << std::endl;
        exit(1);
    }
    //
    // Disable parity.
    //
    m_port->SetParity(SerialStreamBuf::PARITY_NONE);
    if (!m_port->good()) {
        std::cerr << "Error: Could not disable the parity." << std::endl;
        exit(1);
    }
    //
    // Set the number of stop bits.
    //
    m_port->SetNumOfStopBits(1);
    if (!m_port->good()) {
        std::cerr << "Error: Could not set the number of stop bits."
                << std::endl;
        exit(1);
    }
    //
    // Turn off hardware flow control.
    //
    m_port->SetFlowControl(SerialStreamBuf::FLOW_CONTROL_NONE);
    if (!m_port->good()) {
        std::cerr << "Error: Could not use hardware flow control."
                << std::endl;
        exit(1);
    }


    // QIODevice::OpenMode mode = QIODevice::ReadWrite;
    // mode |= QIODevice::Unbuffered;
}

/**
 * Metodo responsavel por gravar os dados
 * para a porta serial.
 */
bool RldSerialPort::WriteInPort(char bytes[]) {
    //
    if (m_port->IsOpen()) {
        //
        cout << FG_BLUE << "\nGravando dados para Porta Serial:  "
                << FG_MAGENTA << bytes << END;

        if (strlen(bytes) > 0) {
            m_port->write(bytes, strlen(bytes));
        }

    } else {
        cerr << FG_RED << "[" << __FILE__ << ":" << __LINE__ << "] " << FG_MAGENTA 
             << "\nErro: Impossivel fazer a Gravacao, porta esta fechada!!" << END;
        return false;
    }

    return true;
}

/**
 * Metodo responsavel por retornar
 * um array de bytes.
 * @return 
 */
string RldSerialPort::ReadAllInPort() {
    //
    const int BUFFER_SIZE = 256;
    char char_buffer[BUFFER_SIZE];
    //
    if (m_port->rdbuf()->in_avail() > 0) {
        //
        m_port->read(char_buffer, BUFFER_SIZE);
        //
        cout << FG_GREEN << "\nEncontrou bytes para leitura!!" << FG_MAGENTA << char_buffer << END << endl;
    } else {
        cout << FG_BLUE << "\nNada para ler!!" << END << endl;
    }
    //
    return string(char_buffer);
}

/**
 * Metodo responsavel por retorna um 
 * um array de bytes com um byte
 * @return 
 */
char RldSerialPort::ReadCharInPort() {
    //Ler um byte
    char c;

    if (m_port->rdbuf()->in_avail() > 0) {
        if (m_port->get(c))
            cout << FG_GREEN << "\nEncontrou um byte: " << FG_MAGENTA << hex << static_cast<int> (c) << END;
    } else {
        cout << FG_BLUE << "\nNada para ler!!" << END << endl;
    }

    //
    return c;
}

/**
 * Verifica se a porta esta aberta
 * caso não esteja retorna falso
 * para que seja tomada uma decisao
 * @return 
 */
bool RldSerialPort::VerifyPort() {
    /**
     * Verifica se a porta foi aberta
     * @param serial_name
     */
    if (!m_port->IsOpen()) {
        cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
                << "Error: Could not open serial port."
                << endl;
        return false;
    }
    //
    return true;
}

/**
 * Metodo responsavel por fechar a porta
 * serial para ser aberta novamente.
 */
void RldSerialPort::ClosePort() {
    m_port->Close();
}